#ifndef __PHAARTYPE_H
#define __PHAARTYPE_H

#include "sdopencv/PHaarFeature.hpp"


namespace sdopencv
{
    class AbstractPHaarType
    {
        public:

        // number of parameters
        int nparams;

        // swapping x and y makes a new feature type
        bool can_swap;

        // 90-degree rorating makes a new feature type
        bool can_rotate90;

        // 180-degree rotateing makes a new feature type
        bool can_rotate180;

        // compute the size
        virtual CvSize size(const std::vector<int> & params) = 0;

        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params) = 0;
    };


    class EdgeType1 : public AbstractPHaarType
    {
        public:

        EdgeType1();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class EdgeType2 : public AbstractPHaarType
    {
        public:

        EdgeType2();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class Corner90Type1 : public AbstractPHaarType
    {
        public:

        Corner90Type1();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class Corner90Type2 : public AbstractPHaarType
    {
        public:

        Corner90Type2();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class Corner45Type : public AbstractPHaarType
    {
        public:

        Corner45Type();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class Corner135Type : public AbstractPHaarType
    {
        public:

        Corner135Type();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class CurveType1 : public AbstractPHaarType
    {
        public:

        CurveType1();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    class CurveType2 : public AbstractPHaarType
    {
        public:

        CurveType2();


        // compute the size
        virtual CvSize size(const std::vector<int> & params);


        // generate a PHaar feature with its top left at (x,y) and with its parameters given
        virtual PHaarFeature generate(int x, int y, const std::vector<int> & params);
    };


    AbstractPHaarType *new_PHaarType(int type_index);
}


#endif
